#!/bin/bash

# xiaozhi-esp32-server Docker全模块自动部署脚本 (Linux/macOS版本)
# 作者: AI Assistant
# 版本: 1.0
# 描述: 自动完成xiaozhi-esp32-server的Docker全模块部署

set -e

# 默认参数
DEPLOY_PATH="xiaozhi-server"
SKIP_MODEL_DOWNLOAD=false
FORCE=false

# 颜色输出函数
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

print_success() {
    echo -e "${GREEN}✓ $1${NC}"
}

print_info() {
    echo -e "${CYAN}ℹ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠ $1${NC}"
}

print_error() {
    echo -e "${RED}✗ $1${NC}"
}

print_header() {
    echo -e "${BLUE}$1${NC}"
}

# 显示帮助信息
show_help() {
    cat << EOF
xiaozhi-esp32-server Docker全模块自动部署脚本

用法:
    $0 [选项]

选项:
    -p, --path <路径>      指定部署目录 (默认: xiaozhi-server)
    -s, --skip-model      跳过语音识别模型下载
    -f, --force           强制覆盖现有目录
    -h, --help            显示此帮助信息

示例:
    $0
    $0 --path /opt/xiaozhi --skip-model
    $0 --force

注意:
    1. 需要预先安装Docker和Docker Compose
    2. 语音识别模型约1GB，下载可能需要较长时间
    3. 部署完成后需要按照提示进行配置
EOF
}

# 解析命令行参数
parse_args() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -p|--path)
                DEPLOY_PATH="$2"
                shift 2
                ;;
            -s|--skip-model)
                SKIP_MODEL_DOWNLOAD=true
                shift
                ;;
            -f|--force)
                FORCE=true
                shift
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            *)
                print_error "未知选项: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

# 检测操作系统
detect_os() {
    if [[ -f /etc/os-release ]]; then
        . /etc/os-release
        OS=$NAME
        VER=$VERSION_ID
    elif type lsb_release >/dev/null 2>&1; then
        OS=$(lsb_release -si)
        VER=$(lsb_release -sr)
    elif [[ -f /etc/redhat-release ]]; then
        OS="Red Hat Enterprise Linux"
        VER=$(cat /etc/redhat-release | sed 's/.*release //' | sed 's/ .*//')
    else
        OS=$(uname -s)
        VER=$(uname -r)
    fi
    
    print_info "检测到操作系统: $OS $VER"
}

# 检测网络环境并选择合适的Docker源
detect_network_and_choose_source() {
    print_info "检测网络环境..."
    
    # 测试是否能访问Docker官方源
    if curl -s --connect-timeout 5 https://download.docker.com/linux/ubuntu/gpg > /dev/null 2>&1; then
        print_info "检测到可以访问Docker官方源"
        USE_CHINA_MIRROR=false
    else
        print_info "检测到无法访问Docker官方源，将使用中国镜像源"
        USE_CHINA_MIRROR=true
    fi
}

# 安装Docker (Ubuntu/Debian)
install_docker_ubuntu() {
    print_info "开始在Ubuntu/Debian系统上安装Docker..."
    
    # 检测网络环境
    detect_network_and_choose_source
    
    # 更新包索引
    print_info "更新包索引..."
    sudo apt-get update
    
    # 安装必要的包
    print_info "安装必要的依赖包..."
    sudo apt-get install -y \
        ca-certificates \
        curl \
        gnupg \
        lsb-release
    
    if [ "$USE_CHINA_MIRROR" = true ]; then
        # 使用阿里云镜像源
        print_info "使用阿里云Docker镜像源..."
        
        # 添加阿里云Docker GPG密钥
        print_info "添加阿里云Docker GPG密钥..."
        sudo mkdir -p /etc/apt/keyrings
        curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
        
        # 设置阿里云Docker仓库
        print_info "设置阿里云Docker仓库..."
        echo \
            "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
            $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    else
        # 使用Docker官方源
        print_info "使用Docker官方源..."
        
        # 添加Docker官方GPG密钥
        print_info "添加Docker官方GPG密钥..."
        sudo mkdir -p /etc/apt/keyrings
        curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
        
        # 设置Docker官方仓库
        print_info "设置Docker官方仓库..."
        echo \
            "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
            $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    fi
    
    # 更新包索引
    print_info "更新包索引..."
    sudo apt-get update
    
    # 安装Docker Engine
    print_info "安装Docker Engine..."
    sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
    # 启动Docker服务
    print_info "启动Docker服务..."
    sudo systemctl start docker
    sudo systemctl enable docker
    
    # 配置Docker镜像加速器（中国大陆用户）
    if [ "$USE_CHINA_MIRROR" = true ]; then
        configure_docker_mirror
    fi
    
    # 将当前用户添加到docker组
    print_info "将当前用户添加到docker组..."
    sudo usermod -aG docker $USER
    
    print_success "Docker安装完成"
    print_warning "注意：需要重新登录或执行 'newgrp docker' 使docker组权限生效"
}

# 配置Docker镜像加速器
configure_docker_mirror() {
    print_info "配置Docker镜像加速器..."
    
    # 创建Docker配置目录
    sudo mkdir -p /etc/docker
    
    # 备份原有配置
    if [ -f /etc/docker/daemon.json ]; then
        print_info "备份原有Docker配置..."
        sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.backup.$(date +%Y%m%d_%H%M%S)
    fi
    
    # 配置多个镜像源（优先使用最稳定的源）
    cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
{
    "registry-mirrors": [
        "https://dockerproxy.com",
        "https://docker.nju.edu.cn",
        "https://docker.mirrors.ustc.edu.cn",
        "https://hub-mirror.c.163.com",
        "https://mirror.baidubce.com",
        "https://ccr.ccs.tencentyun.com",
        "https://docker.m.daocloud.io"
    ],
    "max-concurrent-downloads": 1,
    "max-concurrent-uploads": 1,
    "storage-driver": "overlay2",
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "100m",
        "max-file": "3"
    },
    "live-restore": true,
    "userland-proxy": false,
    "experimental": false,
    "ip-forward": true,
    "iptables": true,
    "bridge": "docker0"
}
EOF
    
    # 重启Docker服务以应用配置
    print_info "重启Docker服务以应用镜像加速器配置..."
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    # 等待Docker服务完全启动
    print_info "等待Docker服务启动..."
    sleep 10
    
    # 验证Docker服务状态
    if ! sudo systemctl is-active --quiet docker; then
        print_warning "Docker服务启动失败，尝试重新启动..."
        sudo systemctl start docker
        sleep 5
    fi
    
    # 验证Docker镜像加速器配置
    print_info "验证Docker镜像加速器配置..."
    if docker info | grep -A 10 "Registry Mirrors" | grep -q "mirror"; then
        print_success "Docker镜像加速器配置成功"
        docker info | grep -A 15 "Registry Mirrors"
    else
        print_warning "Docker镜像加速器配置可能未生效，但将继续部署"
    fi
}

# 下载离线镜像包（备选方案）
download_offline_images() {
    print_info "准备下载离线镜像包..."
    
    local images=(
        "mysql:8.0"
        "redis:7.0-alpine"
        "xiaozhi/xiaozhi-esp32-server:latest"
        "xiaozhi/xiaozhi-esp32-server-web:latest"
    )
    
    local offline_dir="$DEPLOY_DIR/offline_images"
    mkdir -p "$offline_dir"
    
    print_info "尝试从国内镜像源拉取镜像..."
    
    # 配置临时镜像源
    configure_docker_mirror
    
    for image in "${images[@]}"; do
        print_info "尝试拉取镜像: $image"
        
        # 尝试多个策略拉取镜像
        local success=false
        
        # 策略1: 直接拉取
        if timeout 180 docker pull "$image" 2>/dev/null; then
            success=true
        # 策略2: 使用代理镜像源
        elif timeout 180 docker pull "dockerproxy.com/$image" 2>/dev/null; then
            docker tag "dockerproxy.com/$image" "$image"
            docker rmi "dockerproxy.com/$image" 2>/dev/null || true
            success=true
        # 策略3: 使用南京大学镜像源
        elif timeout 180 docker pull "docker.nju.edu.cn/$image" 2>/dev/null; then
            docker tag "docker.nju.edu.cn/$image" "$image"
            docker rmi "docker.nju.edu.cn/$image" 2>/dev/null || true
            success=true
        fi
        
        if [ "$success" = true ]; then
            print_success "成功拉取镜像: $image"
            # 保存镜像到本地文件
            local image_file="${image//\//_}.tar"
            print_info "保存镜像到: $offline_dir/$image_file"
            docker save "$image" | gzip > "$offline_dir/$image_file.gz"
        else
            print_error "拉取镜像失败: $image"
        fi
    done
}

# 加载离线镜像
load_offline_images() {
    local offline_dir="$DEPLOY_DIR/offline_images"
    
    if [ ! -d "$offline_dir" ]; then
        print_warning "离线镜像目录不存在: $offline_dir"
        return 1
    fi
    
    print_info "加载离线镜像..."
    
    for image_file in "$offline_dir"/*.tar.gz; do
        if [ -f "$image_file" ]; then
            print_info "加载镜像: $(basename "$image_file")"
            gunzip -c "$image_file" | docker load
        fi
    done
}

# 手动配置Docker镜像加速器（如果自动配置失败）
manual_configure_docker_mirror() {
    print_warning "检测到Docker镜像拉取问题，正在配置镜像加速器..."
    
    # 停止所有容器
    print_info "停止现有容器..."
    docker compose -f docker-compose_all.yml down 2>/dev/null || true
    
    # 配置镜像加速器
    configure_docker_mirror
    
    print_success "镜像加速器配置完成，请重新运行脚本"
}

# 安装Docker (CentOS/RHEL)
install_docker_centos() {
    print_info "开始在CentOS/RHEL系统上安装Docker..."
    
    # 安装必要的包
    print_info "安装必要的依赖包..."
    sudo yum install -y yum-utils
    
    # 设置稳定版仓库
    print_info "设置Docker仓库..."
    sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
    
    # 安装Docker Engine
    print_info "安装Docker Engine..."
    sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
    # 启动Docker服务
    print_info "启动Docker服务..."
    sudo systemctl start docker
    sudo systemctl enable docker
    
    # 将当前用户添加到docker组
    print_info "将当前用户添加到docker组..."
    sudo usermod -aG docker $USER
    
    print_success "Docker安装完成"
    print_warning "注意：需要重新登录或执行 'newgrp docker' 使docker组权限生效"
}

# 自动安装Docker
auto_install_docker() {
    print_info "Docker未安装，开始自动安装..."
    
    detect_os
    
    case "$OS" in
        *"Ubuntu"*|*"Debian"*)
            install_docker_ubuntu
            ;;
        *"CentOS"*|*"Red Hat"*|*"Rocky"*|*"AlmaLinux"*)
            install_docker_centos
            ;;
        *)
            print_error "不支持的操作系统: $OS"
            print_info "请手动安装Docker: https://docs.docker.com/get-docker/"
            exit 1
            ;;
    esac
    
    # 验证安装
    print_info "验证Docker安装..."
    if command -v docker &> /dev/null; then
        print_success "Docker安装验证成功"
        
        # 尝试启动docker组权限
        if ! docker ps &> /dev/null; then
            print_info "尝试激活docker组权限..."
            newgrp docker << EOF
            docker ps &> /dev/null && print_success "Docker权限验证成功" || print_warning "Docker权限可能需要重新登录才能生效"
EOF
        fi
    else
        print_error "Docker安装验证失败"
        exit 1
    fi
}

# 检查Docker是否安装
check_docker() {
    if ! command -v docker &> /dev/null; then
        print_warning "Docker未安装"
        read -p "是否自动安装Docker? (Y/n): " -r response
        if [[ "$response" =~ ^[Nn]$ ]]; then
            print_info "跳过Docker安装，请手动安装Docker: https://docs.docker.com/get-docker/"
            exit 1
        else
            auto_install_docker
        fi
    fi
    
    if ! docker --version &> /dev/null; then
        print_error "Docker未正确配置或无权限访问"
        print_info "请确保Docker服务正在运行，并且当前用户有权限访问Docker"
        print_info "可以尝试执行: sudo systemctl start docker"
        print_info "或者重新登录以获取docker组权限"
        exit 1
    fi
    
    print_success "Docker已安装: $(docker --version)"
}

# 检查Docker Compose是否可用
check_docker_compose() {
    if ! docker compose version &> /dev/null; then
        print_error "Docker Compose不可用"
        print_info "现代版本的Docker通常包含Docker Compose插件"
        print_info "如果您使用的是旧版本，请升级Docker或单独安装docker-compose"
        exit 1
    fi
    
    print_success "Docker Compose可用: $(docker compose version)"
}

# 创建目录结构
create_directory_structure() {
    local base_path="$1"
    
    print_info "创建目录结构..."
    
    local directories=(
        "$base_path"
        "$base_path/data"
        "$base_path/models"
        "$base_path/models/SenseVoiceSmall"
    )
    
    for dir in "${directories[@]}"; do
        if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
            print_success "创建目录: $dir"
        else
            print_info "目录已存在: $dir"
        fi
    done
}

# 下载文件
download_file() {
    local url="$1"
    local output_path="$2"
    local description="$3"
    
    print_info "下载 $description..."
    
    if command -v wget &> /dev/null; then
        if wget -q --show-progress -O "$output_path" "$url"; then
            print_success "下载完成: $description"
            return 0
        fi
    elif command -v curl &> /dev/null; then
        if curl -L -o "$output_path" "$url" --progress-bar; then
            print_success "下载完成: $description"
            return 0
        fi
    else
        print_error "未找到wget或curl命令"
        return 1
    fi
    
    print_error "下载失败: $description"
    return 1
}

# 下载配置文件
download_config_files() {
    local base_path="$1"
    
    print_info "下载配置文件..."
    
    # 下载docker-compose_all.yml
    local compose_url="https://raw.githubusercontent.com/xinnan-tech/xiaozhi-esp32-server/refs/heads/main/main/xiaozhi-server/docker-compose_all.yml"
    local compose_path="$base_path/docker-compose_all.yml"
    
    if ! download_file "$compose_url" "$compose_path" "docker-compose_all.yml"; then
        return 1
    fi
    
    # 下载config_from_api.yaml
    local config_url="https://raw.githubusercontent.com/xinnan-tech/xiaozhi-esp32-server/refs/heads/main/main/xiaozhi-server/config_from_api.yaml"
    local config_path="$base_path/data/.config.yaml"
    
    if ! download_file "$config_url" "$config_path" "config_from_api.yaml"; then
        return 1
    fi
    
    print_success "配置文件下载完成"
    return 0
}

# 下载语音识别模型
download_sense_voice_model() {
    local base_path="$1"
    local model_path="$base_path/models/SenseVoiceSmall/model.pt"
    
    if [[ -f "$model_path" ]]; then
        print_info "语音识别模型已存在，跳过下载"
        return 0
    fi
    
    print_info "下载语音识别模型文件 (约1GB，可能需要较长时间)..."
    print_warning "如果下载失败，请手动从以下地址下载并放置到 $model_path"
    print_info "线路一: https://modelscope.cn/models/iic/SenseVoiceSmall/resolve/master/model.pt"
    print_info "线路二: 百度网盘 https://pan.baidu.com/share/init?surl=QlgM58FHhYv1tFnUT_A8Sg&pwd=qvna 提取码: qvna"
    
    # 尝试从阿里魔搭下载
    local model_url="https://modelscope.cn/models/iic/SenseVoiceSmall/resolve/master/model.pt"
    
    if download_file "$model_url" "$model_path" "语音识别模型"; then
        print_success "语音识别模型下载完成"
        return 0
    else
        print_warning "自动下载模型失败"
        print_warning "请手动下载模型文件并放置到: $model_path"
        return 1
    fi
}

# 清理旧容器和镜像
cleanup_old_containers() {
    local base_path="$1"
    
    print_info "清理旧版本容器和镜像..."
    
    cd "$base_path"
    
    # 停止并删除容器
    docker compose -f docker-compose_all.yml down 2>/dev/null || true
    
    local containers=(
        "xiaozhi-esp32-server"
        "xiaozhi-esp32-server-web"
        "xiaozhi-esp32-server-db"
        "xiaozhi-esp32-server-redis"
    )
    
    for container in "${containers[@]}"; do
        docker stop "$container" 2>/dev/null || true
        docker rm "$container" 2>/dev/null || true
    done
    
    # 删除旧镜像
    local images=(
        "ghcr.nju.edu.cn/xinnan-tech/xiaozhi-esp32-server:server_latest"
        "ghcr.nju.edu.cn/xinnan-tech/xiaozhi-esp32-server:web_latest"
    )
    
    for image in "${images[@]}"; do
        docker rmi "$image" 2>/dev/null || true
    done
    
    print_success "旧容器和镜像清理完成"
    cd - > /dev/null
}

# 预拉取Docker镜像
pull_docker_images() {
    print_info "预拉取Docker镜像..."
    
    cd "$DEPLOY_DIR"
    
    # 设置Docker拉取超时时间
    export DOCKER_CLIENT_TIMEOUT=600
    export COMPOSE_HTTP_TIMEOUT=600
    
    # 先尝试加载离线镜像
    if [ -d "$DEPLOY_DIR/offline_images" ]; then
        print_info "检测到离线镜像，尝试加载..."
        load_offline_images
    fi
    
    # 逐个拉取镜像，使用多种策略
    local services=("xiaozhi-esp32-server" "xiaozhi-esp32-server-web" "xiaozhi-esp32-server-db" "xiaozhi-esp32-server-redis")
    
    for service in "${services[@]}"; do
        print_info "拉取 $service 镜像..."
        
        # 策略1: 使用compose直接拉取
        if timeout 180 docker compose -f docker-compose_all.yml pull "$service" 2>/dev/null; then
            print_success "$service 镜像拉取成功"
            continue
        fi
        
        # 策略2: 手动从镜像加速器拉取
        print_info "尝试从镜像加速器拉取 $service..."
        local image_name
        case "$service" in
            "xiaozhi-esp32-server-db")
                image_name="mysql:8.0"
                ;;
            "xiaozhi-esp32-server-redis")
                image_name="redis:7.0-alpine"
                ;;
            *)
                # 从compose文件中提取镜像名
                image_name=$(grep -A 5 "$service:" docker-compose_all.yml | grep "image:" | awk '{print $2}' | head -1)
                ;;
        esac
        
        if [ -n "$image_name" ]; then
            local success=false
            
            # 尝试多个镜像源
            local mirrors=("dockerproxy.com" "docker.nju.edu.cn" "docker.mirrors.ustc.edu.cn")
            
            for mirror in "${mirrors[@]}"; do
                print_info "尝试从 $mirror 拉取 $image_name..."
                if timeout 120 docker pull "$mirror/$image_name" 2>/dev/null; then
                    docker tag "$mirror/$image_name" "$image_name"
                    docker rmi "$mirror/$image_name" 2>/dev/null || true
                    success=true
                    break
                fi
            done
            
            if [ "$success" = true ]; then
                print_success "$service 镜像拉取成功（通过镜像源）"
            else
                print_warning "$service 镜像拉取失败，将在启动时自动拉取"
            fi
        else
            print_warning "$service 镜像拉取失败，将在启动时自动拉取"
        fi
    done
    
    print_success "镜像拉取阶段完成"
}

# 启动Docker容器
start_containers() {
    print_info "启动Docker容器..."
    
    cd "$DEPLOY_DIR"
    
    # 设置Docker启动超时时间
    export DOCKER_CLIENT_TIMEOUT=600
    export COMPOSE_HTTP_TIMEOUT=600
    
    # 检查是否存在网络连接问题
    if ! docker info > /dev/null 2>&1; then
        print_error "Docker服务未正常运行"
        return 1
    fi
    
    # 先尝试预拉取镜像
    pull_docker_images
    
    # 分阶段启动容器，提高成功率
    print_info "分阶段启动容器..."
    
    # 第一阶段：启动基础服务（数据库和Redis）
    print_info "第一阶段：启动基础服务..."
    
    print_info "启动数据库服务..."
    if ! timeout 300 docker compose -f docker-compose_all.yml up -d xiaozhi-esp32-server-db; then
        print_error "数据库服务启动失败"
        docker compose -f docker-compose_all.yml logs xiaozhi-esp32-server-db
        return 1
    fi
    
    print_info "启动Redis服务..."
    if ! timeout 300 docker compose -f docker-compose_all.yml up -d xiaozhi-esp32-server-redis; then
        print_error "Redis服务启动失败"
        docker compose -f docker-compose_all.yml logs xiaozhi-esp32-server-redis
        return 1
    fi
    
    # 等待基础服务启动
    print_info "等待基础服务启动完成..."
    sleep 10
    
    # 检查基础服务状态
    if ! docker compose -f docker-compose_all.yml ps | grep -E "(xiaozhi-esp32-server-db|xiaozhi-esp32-server-redis)" | grep -q "Up"; then
        print_error "基础服务启动异常"
        docker compose -f docker-compose_all.yml ps
        return 1
    fi
    
    print_success "基础服务启动成功"
    
    # 第二阶段：启动应用服务
    print_info "第二阶段：启动应用服务..."
    
    print_info "启动主服务..."
    if ! timeout 300 docker compose -f docker-compose_all.yml up -d xiaozhi-esp32-server; then
        print_warning "主服务启动失败，查看日志..."
        docker compose -f docker-compose_all.yml logs xiaozhi-esp32-server
        
        # 尝试重新启动
        print_info "尝试重新启动主服务..."
        docker compose -f docker-compose_all.yml restart xiaozhi-esp32-server
        sleep 5
    fi
    
    print_info "启动Web服务..."
    if ! timeout 300 docker compose -f docker-compose_all.yml up -d xiaozhi-esp32-server-web; then
        print_warning "Web服务启动失败，查看日志..."
        docker compose -f docker-compose_all.yml logs xiaozhi-esp32-server-web
        
        # 尝试重新启动
        print_info "尝试重新启动Web服务..."
        docker compose -f docker-compose_all.yml restart xiaozhi-esp32-server-web
        sleep 5
    fi
    
    # 等待所有服务启动
    print_info "等待所有服务启动完成..."
    sleep 15
    
    # 检查所有容器状态
    print_info "检查所有容器状态..."
    docker compose -f docker-compose_all.yml ps
    
    # 检查容器健康状态
    print_info "检查容器健康状态..."
    local healthy_count=0
    for i in {1..30}; do
        local running_containers=$(docker compose -f docker-compose_all.yml ps --format "table {{.Service}}\t{{.State}}" | grep -c "running" || echo "0")
        
        if [ "$running_containers" -ge 3 ]; then
            print_success "容器启动完成，运行中的容器数: $running_containers"
            healthy_count=$running_containers
            break
        fi
        
        print_info "等待容器启动... ($i/30) 当前运行容器数: $running_containers"
        sleep 3
    done
    
    # 最终状态检查
    if [ "$healthy_count" -ge 2 ]; then
        print_success "Docker容器启动成功"
        
        # 显示最终状态
        print_info "最终容器状态:"
        docker compose -f docker-compose_all.yml ps
        
        return 0
    else
        print_error "Docker容器启动失败或不完整"
        
        print_info "容器日志信息:"
        docker compose -f docker-compose_all.yml logs --tail=20
        
        # 检查是否是网络问题
        if docker compose -f docker-compose_all.yml logs 2>&1 | grep -q "registry-1.docker.io\|timeout\|connection refused"; then
            print_warning "检测到网络连接问题，建议:"
            print_info "1. 检查网络连接"
            print_info "2. 重新运行脚本"
            print_info "3. 尝试手动配置Docker镜像加速器"
        fi
        
        return 1
    fi
}

# 显示部署后的配置指南
show_post_deployment_guide() {
    local base_path="$1"
    
    print_success "部署完成！"
    echo
    print_header "=== 重要配置步骤 ==="
    echo
    print_info "1. 打开浏览器访问智控台: http://127.0.0.1:8002"
    print_info "2. 注册第一个用户（将成为超级管理员）"
    echo
    print_info "3. 完成以下三个重要配置："
    echo
    print_warning "   第一步：配置server.secret"
    print_info "   - 登录智控台 → 参数管理 → 找到 server.secret"
    print_info "   - 复制参数值"
    print_info "   - 编辑 $base_path/data/.config.yaml"
    print_info "   - 将 url 改为: http://xiaozhi-esp32-server-web:8002/xiaozhi"
    print_info "   - 将 secret 改为复制的值"
    echo
    print_warning "   第二步：配置智谱AI密钥"
    print_info "   - 智控台 → 模型配置 → 大语言模型 → 智谱AI → 修改"
    print_info "   - 填入您的智谱AI API密钥"
    echo
    print_warning "   第三步：配置接口地址"
    print_info "   - 参数管理 → server.websocket → 填入: ws://您的IP:8000/xiaozhi/v1/"
    print_info "   - 参数管理 → server.ota → 填入: http://您的IP:8002/xiaozhi/ota/"
    echo
    print_info "4. 重启xiaozhi-esp32-server容器:"
    print_success "   docker restart xiaozhi-esp32-server"
    echo
    print_info "5. 查看日志确认启动成功:"
    print_success "   docker logs -f xiaozhi-esp32-server"
    echo
    print_warning "注意：如果语音识别模型下载失败，请手动下载并放置到:"
    print_info "$base_path/models/SenseVoiceSmall/model.pt"
}

# 主函数
main() {
    print_header "=== xiaozhi-esp32-server Docker全模块自动部署脚本 ==="
    echo
    
    # 检查Docker环境
    check_docker
    check_docker_compose
    
    # 获取绝对路径
    DEPLOY_PATH=$(realpath "$DEPLOY_PATH")
    print_info "部署路径: $DEPLOY_PATH"
    
    # 检查目录是否存在且不为空
    if [[ -d "$DEPLOY_PATH" ]] && [[ -n "$(ls -A "$DEPLOY_PATH" 2>/dev/null)" ]]; then
        if [[ "$FORCE" != true ]]; then
            print_warning "目标目录 '$DEPLOY_PATH' 已存在且不为空"
            read -p "是否继续？这可能会覆盖现有文件 (y/N): " -r response
            if [[ ! "$response" =~ ^[Yy]$ ]]; then
                print_info "部署已取消"
                exit 0
            fi
        fi
    fi
    
    # 1. 创建目录结构
    create_directory_structure "$DEPLOY_PATH"
    
    # 2. 下载配置文件
    if ! download_config_files "$DEPLOY_PATH"; then
        print_error "配置文件下载失败，部署终止"
        exit 1
    fi
    
    # 3. 下载语音识别模型（可选）
    if [[ "$SKIP_MODEL_DOWNLOAD" != true ]]; then
        download_sense_voice_model "$DEPLOY_PATH"
    else
        print_warning "跳过语音识别模型下载，请稍后手动下载"
    fi
    
    # 4. 清理旧容器
    cleanup_old_containers "$DEPLOY_PATH"
    
    # 5. 启动新容器
    DEPLOY_DIR="$DEPLOY_PATH"
    
    # 提供离线部署选项
    echo
    read -p "是否尝试离线部署模式？(如果网络不稳定建议选择) [y/N]: " use_offline
    if [[ $use_offline =~ ^[Yy]$ ]]; then
        print_info "启用离线部署模式..."
        download_offline_images
    fi
    
    # 尝试多次启动，提高成功率
    local max_attempts=3
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        print_info "第 $attempt 次尝试启动容器..."
        
        if start_containers; then
            print_success "容器启动成功！"
            break
        else
            print_warning "第 $attempt 次启动失败"
            
            if [ $attempt -lt $max_attempts ]; then
                print_info "等待30秒后重试..."
                sleep 30
                
                # 清理失败的容器
                print_info "清理失败的容器..."
                docker compose -f "$DEPLOY_DIR/docker-compose_all.yml" down 2>/dev/null || true
                
                # 如果是第二次尝试，重新配置镜像加速器
                if [ $attempt -eq 2 ]; then
                    print_info "重新配置Docker镜像加速器..."
                    configure_docker_mirror
                    
                    # 询问是否尝试离线模式
                    if [[ ! $use_offline =~ ^[Yy]$ ]]; then
                        echo
                        read -p "是否尝试离线部署模式？[y/N]: " try_offline
                        if [[ $try_offline =~ ^[Yy]$ ]]; then
                            download_offline_images
                        fi
                    fi
                fi
            else
                print_error "容器启动失败，已尝试 $max_attempts 次"
                print_info "可能的解决方案："
                print_info "1. 检查网络连接是否正常"
                print_info "2. 重新运行脚本以重试部署"
                print_info "3. 手动配置Docker镜像加速器后重试"
                print_info "4. 查看容器日志: docker compose -f $DEPLOY_DIR/docker-compose_all.yml logs"
                print_info "5. 尝试离线部署模式"
                print_info "6. 联系技术支持获取离线安装包"
                exit 1
            fi
        fi
        
        ((attempt++))
    done
    
    # 6. 显示配置指南
    show_post_deployment_guide "$DEPLOY_PATH"
}

# 解析命令行参数
parse_args "$@"

# 执行主函数
main